home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Technotools
/
Technotools (Chestnut CD-ROM)(1993).ISO
/
misc_pto
/
msc2bc
/
mscgrf.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-12-05
|
50KB
|
1,654 lines
/*
GRAPHICS DEMO FOR Microsoft C6.0a graph.h
Produces results comparable to those from BGIGRF.C
Copyright (c) 1991 Borland International. All rights reserved.
From the command line, use:
cl mscgrf.c
*/
#include <dos.h>
#include <math.h>
#include <limits.h>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <time.h>
#include <graph.h>
/* Note 1 - Add the random function, and redefine RAND_MAX from stdlib.h */
#undef RAND_MAX
#define RAND_MAX 0x7FFFU
/* generate an integer random number in the range 0-(num-1) */
#define random(num)(int)(((long)rand()*(num))/(long)(RAND_MAX+1))
/* torad converts degrees to radians */
#define torad( d ) (( (double)(d) * PI ) / 180.0 )
/* Note 2 - FONT_PATH is the location of the .FON files used by this program.
Edit it as appropriate for your environment.
*/
#define FONT_PATH "g:\\c600\\source\\samples\\*.FON"
/* Note 3 - COLORS, HORIZ_DIR, VERT_DIR, FILLS, predefined fill patterns,
viewporttype, and SOLID_STYLE are defined below.
The curr_vp structure is used to keep track of the current state of the
viewport.
*/
enum COLORS
{
BLACK, /* dark colors */
BLUE,
GREEN,
CYAN,
RED,
MAGENTA,
BROWN,
LIGHTGRAY,
DARKGRAY, /* light colors */
LIGHTBLUE,
LIGHTGREEN,
LIGHTCYAN,
LIGHTRED,
LIGHTMAGENTA,
YELLOW,
WHITE
};
#define HORIZ_DIR 0 /* left to right */
#define VERT_DIR 1 /* bottom to top */
enum FILLS
{ EMPTY_FILL, SOLID_FILL, LINE_FILL, LTSLASH_FILL, SLASH_FILL, BKSLASH_FILL,
LTBKSLASH_FILL, HATCH_FILL, XHATCH_FILL, INTERLEAVE_FILL, WIDE_DOT_FILL,
CLOSE_DOT_FILL
};
static char patterns[][8] = {
/* Empty_Fill, fills area in background color */
{ 0, 0, 0, 0, 0, 0, 0, 0 },
/* Solid_Fill, fills area in solid fill color */
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
/* Line_Fill, --- fill */
{ 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF, 0 },
/* LtSlash_Fill, /// fill */
{ 0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88 },
/* Slash_Fill, /// fill with thick lines */
{ 0x33, 0x66, 0xCC, 0x99, 0x33, 0x66, 0xCC, 0x99 },
/* BkSlash_Fill, \\\ fill with thick lines */
{ 0x99, 0xCC, 0x66, 0x33, 0x99, 0xCC, 0x66, 0x33 },
/* LtBkSlash_Fill, \\\ fill */
{ 0x88, 0x44, 0x22, 0x11, 0x88, 0x44, 0x22, 0x11 },
/* Hatch_Fill, light hatch fill */
{ 0x88, 0x55, 0x22, 0x55, 0x88, 0x55, 0x22, 0x55 },
/* XHatch_Fill, heavy cross hatch fill */
{ 0x77, 0xAA, 0xDD, 0xAA, 0x77, 0xAA, 0xDD, 0xAA },
/* Interleave_Fill, interleaving line fill */
{ 0x01, 0x01, 0x01, 0xFF, 0x01, 0x01, 0x01, 0xFF },
/* Wide_Dot_Fill, widely spaced dot fill */
{ 0x88, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00 },
/* Close_Dot_Fill, Closely spaced dot fill */
{ 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22 }
//* { 0x77, 0xFF, 0xFF, 0xFF, 0x77, 0xFF, 0xFF, 0xFF } */
};
struct viewporttype
{
int left, top, right, bottom;
int clip;
};
#define SOLID_STYLE 0xFFFF
struct viewporttype curr_vp; /* Current viewport */
#define ESC 0x1b /* Define the escape key */
#define TRUE 1 /* Define some handy constants */
#define FALSE 0 /* Define some handy constants */
#define PI 3.14159 /* Define a value for PI */
#define ON 1 /* Define some handy constants */
#define OFF 0 /* Define some handy constants */
/* Note 4 - Define the necessary tables to keep track of the attributes
of each Microsoft .FON file, and the font family names.
*/
#define NFONTS 300 /* 300 fonts should be enough */
#define NFONTNAMES 100 /* 100 font names should be enough */
struct _fontinfo Fonts[NFONTS];
unsigned char Font_Names[NFONTNAMES][20];
/* Note 5 - Microsoft C graphics has no built-in data about shape fill styles,
line drawing styles, and text justification.
*/
char *FillStyles[] = {
"EmptyFill", "SolidFill", "LineFill", "LtSlashFill",
"SlashFill", "BkSlashFill", "LtBkSlashFill", "HatchFill",
"XHatchFill", "InterleaveFill", "WideDotFill", "CloseDotFill"
};
char *TextDirect[] = {
"HorizDir", "VertDir"
};
struct PTS {
int x, y;
}; /* Structure to hold vertex points */
/* Note 6 - The Microsoft graph.h structure videoconfig contains information
about the configuration of the video adapter on which this program is
being run after _getvideoconfig is called. The global variables below
contain information about the state of the Microsoft graphics system.
*/
struct videoconfig vc; /* Video configuration info */
int GraphDriver; /* The Graphics device driver */
int GraphMode; /* The Graphics mode value */
double AspectRatio; /* Aspect ratio of a pixel on the screen*/
int MaxX, MaxY; /* The maximum resolution of the screen */
int MaxColors; /* The maximum # of colors available */
int ErrorCode; /* Reports any graphics errors */
int nfonts; /* Number of fonts available */
int nfont_names; /* Number of typefaces available */
int dfont_ndx, dfont_ht; /* Default font index & height(Courier) */
int roman_ndx, rfont_ht; /* Roman font index & height */
struct xycoord cp; /* Current x,y position of graphics */
int gwritemode; /* Current graphics write mode */
/* */
/* Function prototypes */
/* */
void Initialize(void);
void ReportStatus(void);
void TextDump(void);
void RandomBars(void);
void TextDemo(void);
void ColorDemo(void);
void ArcDemo(void);
void CircleDemo(void);
void PieDemo(void);
void BarDemo(void);
void PutPixelDemo(void);
void PutImageDemo(void);
void LineToDemo(void);
void CRTModeDemo(void);
void UserLineStyleDemo(void);
void FillStyleDemo(void);
void PaletteDemo(void);
void PolyDemo(void);
void SayGoodbye(void);
void Pause(void);
void MainWindow(char *header);
void StatusLine(char *msg);
void DrawBorder(void);
void changetextstyle(char *font, int direction, int charht, int charwid);
int gprintf(int *xloc, int *yloc, char *fmt, ... );
/* Note 7 - Microsoft C does not have a built-in delay function, so we have
to do it ourselves.
*/
void delay( clock_t wait );
/* */
/* Begin main function */
/* */
int main()
{
Initialize(); /* Set system into Graphics mode */
ReportStatus(); /* Report results of the initialization */
ColorDemo(); /* Begin actual demonstration */
if( GraphDriver==_EGA || GraphDriver==_VGA )
PaletteDemo();
PutPixelDemo();
PutImageDemo();
BarDemo();
RandomBars();
ArcDemo();
CircleDemo();
PieDemo();
LineToDemo();
UserLineStyleDemo();
TextDump();
TextDemo();
CRTModeDemo();
FillStyleDemo();
PolyDemo();
SayGoodbye(); /* Give user the closing screen */
/* Note 8 - Reset the graphics adapter to text mode with _setvideomode
before exiting from a Microsoft C graphics program.
*/
_setvideomode( _DEFAULTMODE ); /* Return the system to text mode */
return(0);
}
/* */
/* Note 9 - INITIALIZE: Initializes the graphics system and reports */
/* any errors which occured. */
/* */
void Initialize(void)
{
int i, j, font;
int roman_found;
int namematch;
unsigned char list[20];
_setvideomode (_MAXRESMODE);
_getvideoconfig ( &vc );
/* These variables are initialized for convenience, and to give symmetry
between the Microsoft C and Borland C++ versions of this program.
*/
GraphDriver = vc.adapter;
GraphMode = vc.mode;
MaxColors = vc.numcolors; /* Read maximum number of colors*/
MaxX = vc.numxpixels-1;
MaxY = vc.numypixels-1; /* Read size of screen */
/* initial viewport settings */
curr_vp.left = 0;
curr_vp.top = 0;
curr_vp.right = MaxX;
curr_vp.bottom = MaxY;
/* Get correction factor
Note that 4/3 ratio should come out 1:1
*/
AspectRatio = (double)vc.numxpixels / (double)vc.numypixels * (3.0/4.0);
gwritemode = _getwritemode();
/* Get number of available fonts */
nfonts = _registerfonts(FONT_PATH);
nfont_names = 0;
dfont_ht = INT_MAX;
roman_found = 0;
for( font=1 ; font<=nfonts ; ++font )
{ /* For each available font */
sprintf (list, "n%d", font );
if( _setfont( list ) >= 0 )
{
if( _getfontinfo( &(Fonts[font])) )
{
_outtext( "Error: Can't get font information" );
break;
}
}
/* Use smallest Courier as default font.
If Courier is not registered, choose the
smallest bitmapped font registered.
*/
if (Fonts[font].type == 0) /* bitmapped font */
{
if ((strcmp(Fonts[font].facename, "Courier"))==0)
{
if(dfont_ht > Fonts[font].pixheight )
{
dfont_ht = Fonts[font].pixheight;
dfont_ndx = font;
}
}
}
else /* Vector fonts */
if (roman_found == 0) /* Roman found yet? */
{
roman_ndx = font;
rfont_ht = Fonts[font].pixheight;
if ((strcmp(Fonts[font].facename, "Roman"))==0)
roman_found = 1;
}
/* Tabulate the names of all the type faces */
namematch = 0;
if (nfont_names > 0)
for( j=1 ; j<=nfont_names ; ++j )
{
if ((strcmp(Fonts[font].facename, &(Font_Names[nfont_names][0])))==0)
{
namematch = 1;
break;
}
}
if (namematch == 0)
{
++nfont_names;
strcpy (&(Font_Names[nfont_names][0]),Fonts[font].facename);
}
}
}
/* */
/* Note 10 - REPORTSTATUS: Report the current configuration of the */
/* system after the auto-detect initialization. */
/* */
void ReportStatus(void)
{
struct viewporttype viewinfo; /* Params for inquiry procedures*/
char driver[50], mode[50], wmode[50]; /* Strings for driver and mode */
unsigned char savemask[8];
int x, y, j;
cp = _getcurrentposition ();
x = 10;
y = 4;
MainWindow( "Status report after _getvideoconfig" );
switch ( GraphDriver )
{
case _MDPA:
strcpy(driver,"Monochrome Display Adapter");
break;
case _CGA:
strcpy(driver,"Color Graphics Adapter");
break;
case _OCGA:
strcpy(driver,"Olivetti/AT&T Color Graphics Adapter");
break;
case _EGA:
strcpy(driver,"Enhanced Graphics Adapter");
break;
case _OEGA:
strcpy(driver,"Olivetti/AT&T Enhanced Graphics Adapter");
break;
case _VGA:
strcpy(driver,"Video Graphics Array");
break;
case _OVGA:
strcpy(driver,"Olivetti/AT&T Video Graphics Array");
break;
case _MCGA:
strcpy(driver,"Multicolor Graphics Array");
break;
case _HGC:
strcpy(driver,"Hercules Graphics Card");
break;
default: strcpy(driver,"Unknown Graphics Adapter");
};
switch ( gwritemode )
{
case _GAND:
strcpy(wmode,"_GAND");
break;
case _GOR:
strcpy(wmode,"_GOR");
break;
case _GPRESET:
strcpy(wmode,"_GPRESET");
break;
case _GPSET:
strcpy(wmode,"_GPSET");
break;
case _GXOR:
strcpy(wmode,"_GXOR");
break;
default: strcpy(wmode,"Unknown Graphics Write Mode");
};
gprintf( &x, &y, "Graphics device : %-20s (%d)", driver, GraphDriver );
/* Can also add MSC text name for mode */
gprintf( &x, &y, "Graphics mode : Mode = %d", GraphMode );
gprintf( &x, &y, "Screen resolution : ( 0, 0, %d, %d )",
vc.numxpixels, vc.numypixels );
gprintf( &x, &y, "Current view port : ( %d, %d, %d, %d )",
curr_vp.left, curr_vp.top, curr_vp.right, curr_vp.bottom );
gprintf( &x, &y, "Current position : ( %d, %d )", cp.xcoord, cp.ycoord);
gprintf( &x, &y, "Colors available : %d", MaxColors );
gprintf( &x, &y, "Current color : %d", _getcolor() );
gprintf( &x, &y, "Line style : 0x%x", _getlinestyle() );
if (_getfillmask(savemask) == NULL)
gprintf( &x, &y, "Current fill mask : NONE" );
else
gprintf( &x, &y, "Current fill mask : 0x%x2%x2%x2%x2%x2%x2%x2%x2",
savemask[0], savemask[1], savemask[2], savemask[3],
savemask[4], savemask[5], savemask[6], savemask[7] );
gprintf( &x, &y, "Graphics write mode: Mode = %s (0x%x)",
wmode, gwritemode );
gprintf( &x, &y, "Number of fonts : %d", nfonts );
for( j=1 ; j<=nfont_names ; ++j )
{
gprintf( &x, &y, "%-20s %s", (j==1) ? "The typefaces are :" : " ",
Font_Names[j] );
}
Pause(); /* Pause for user to read screen */
}
/* */
/* Note 11 - TEXTDUMP: Display all the characters in each of the */
/* available fonts. */
/* */
void TextDump()
{
char buffer[80];
int font, ch, wwidth, lwidth;
struct viewporttype vp;
for( font=1 ; font<=nfonts ; ++font )
{ /* For each available font */
sprintf( buffer, "%s %s Font, %d Points",
(Fonts[font].type==0) ? "Bitmapped" : "Scalable",
Fonts[font].facename, Fonts[font].pixheight );
MainWindow( buffer ); /* Display fontname as banner */
vp.left = curr_vp.left;
vp.top = curr_vp.top;
vp.right = curr_vp.right;
vp.bottom = curr_vp.bottom;
cp = _moveto( 2, 3 ); /* Starting position of first line of text */
buffer[1] = '\0'; /* Terminate a string of one character */
changetextstyle( Fonts[font].facename, HORIZ_DIR,
Fonts[font].pixheight, Fonts[font].avgwidth );
ch = '!'; /* Begin at 1st printable */
while( ch < 256 )
{ /* For each possible character */
buffer[0] = ch; /* Put character into a string */
lwidth = _getgtextextent ( buffer ); /* Width of this character */
if( (cp.xcoord + lwidth+3) >= vp.right)
/* This line is filled so start a new line of text */
cp = _moveto( 2, cp.ycoord + Fonts[font].pixheight + 3 );
_outgtext( buffer ); /* send string to screen */
cp = _getcurrentposition ();
++ch; /* Goto the next character */
}
Pause(); /* Pause until user acks */
} /* End of FONT loop */
}
/* */
/* Note 12 - RANDOMBARS: Display random bars */
/* */
void RandomBars(void)
{
int color;
int x1, y1, x2, y2;
int prevwritemode;
MainWindow( "Random Rectangles" );
StatusLine( "Esc aborts or press a key..." ); /* Put msg at bottom of screen */
prevwritemode = _setwritemode ( _GPSET );
while( !kbhit() )
{ /* Until user enters a key... */
x1 = random( MaxX );
y1 = random( MaxY );
x2 = random( MaxX );
y2 = random( MaxY );
/* The images drawn are normally transparent, i.e. what was written
previously shows through the fill pattern.
So we blacken out the area first to achieve the desired effect.
*/
_setcolor( BLACK ); /* First clear out area */
_setfillmask( patterns[SOLID_FILL] );
_rectangle (_GFILLINTERIOR, x1, y1, x2, y2 );
color = random( MaxColors-1 )+1;
_setcolor( color );
_setfillmask( patterns[random(11)] );
_rectangle (_GBORDER, x1, y1, x2, y2 );
_rectangle (_GFILLINTERIOR, x1, y1, x2, y2 );
}
_setwritemode (prevwritemode);
Pause(); /* Pause for user's response */
}
/* */
/* Note 13 - TEXTDEMO: Show each font to the user in several sizes. */
/* */
void TextDemo(void)
{
float charsize[] = { .375, 0.5, .75, 1.0 };
int font;
float size, dsize;
int h, x, y, i, j, lwidth, vh_done;
struct viewporttype vp;
char buffer[80];
for( j=1 ; j<=nfont_names ; ++j )
/* Enumerate all font names */
{
sprintf( buffer, "%s Font Demonstration", Font_Names[j] );
MainWindow( buffer );
vp.left = curr_vp.left;
vp.top = curr_vp.top;
vp.right = curr_vp.right;
vp.bottom = curr_vp.bottom;
vh_done = 0; /* Haven't displayed vertical/horizontal text yet
for this font family */
/* Enumerate all the fonts in the table */
for( font=1 ; font<=nfonts ; ++font )
if ((strcmp(Fonts[font].facename, &(Font_Names[j][0])))==0)
/* Font name matches current font name, so display it */
if (Fonts[font].type == 1)
{ /* Vector font */
dsize = 0.5;
/* Display at 1/2 of pixel height */
changetextstyle( Fonts[font].facename, VERT_DIR,
(int)(Fonts[font].pixheight*dsize),
(int)(Fonts[font].avgwidth*dsize) );
cp = _moveto ((int)(2*Fonts[font].avgwidth*dsize),
vp.bottom - (int)(2*Fonts[font].pixheight*dsize) );
_outgtext ( "Vertical" );
cp = _getcurrentposition ();
changetextstyle( Fonts[font].facename, HORIZ_DIR,
(int)(Fonts[font].pixheight*dsize),
(int)(Fonts[font].avgwidth*dsize) );
cp = _moveto ( (int)(2*Fonts[font].avgwidth*dsize), 2 );
_outgtext ( "Horizontal" );
cp = _getcurrentposition ();
x = (vp.right - vp.left) / 2;
y = Fonts[font].pixheight;
for( i=1 ; i<=5 ; ++i )
{ /* For each of the sizes */
if (i!=5)
{
size = charsize[i-1];
h = (int)(Fonts[font].pixheight*size);
changetextstyle( Fonts[font].facename, HORIZ_DIR,
h, (int)(Fonts[font].avgwidth*size) );
sprintf( buffer, "%d Points", h );
}
else
{
size = 3.0/2.0;
h = (int)(Fonts[font].pixheight*size);
changetextstyle( Fonts[font].facename, HORIZ_DIR,
h, (int)(Fonts[font].avgwidth*5.0/6.0) );
sprintf( buffer, "%d Points, 3/2xH, 5/6xW", h );
}
y += h;
lwidth = _getgtextextent (buffer);
cp = _moveto ( x-(lwidth/2), y ); /* Centered */
_outgtext ( buffer );
cp = _getcurrentposition ();
} /* for i */
} /* Fonts[font].type == 1 */
else
{ /* Bitmapped font */
if (vh_done == 0)
{
vh_done = 1;
changetextstyle( Fonts[font].facename, VERT_DIR,
Fonts[font].pixheight, Fonts[font].avgwidth );
cp = _moveto (2*Fonts[font].avgwidth,
vp.bottom - 2*Fonts[font].pixheight );
_outgtext ( "Vertical" );
cp = _getcurrentposition ();
changetextstyle( Fonts[font].facename, HORIZ_DIR,
Fonts[font].pixheight, Fonts[font].avgwidth );
cp = _moveto ( 2*Fonts[font].avgwidth, 2 );
_outgtext ( "Horizontal" );
cp = _getcurrentposition ();
x = (vp.right - vp.left) / 2;
y = Fonts[font].pixheight;
}
h = Fonts[font].pixheight;
changetextstyle( Fonts[font].facename, HORIZ_DIR, h,
Fonts[font].avgwidth );
sprintf( buffer, "%d Points", h );
y += h;
lwidth = _getgtextextent (buffer);
cp = _moveto ( x-(lwidth/2), y ); /* Centered */
_outgtext ( buffer );
cp = _getcurrentposition ();
} /* Bitmapped font family */
Pause(); /* Pause to let user look */
} /* for j */
}
/* */
/* Note 14 - COLORDEMO: Display the current color palette on the screen.*/
/* */
void ColorDemo(void)
{
struct viewporttype vp;
int color, height, width;
int twidth;
int x, y, i, j;
char cnum[5];
MainWindow( "Color Demonstration" ); /* Show demonstration name */
color = 1;
vp.left = curr_vp.left;
vp.top = curr_vp.top;
vp.right = curr_vp.right;
vp.bottom = curr_vp.bottom;
width = 2 * ( (vp.right+1) / 16 ); /* Get box dimensions */
height = 2 * ( (vp.bottom-10) / 10 );
x = width / 2;
y = height / 2; /* Leave 1/2 box border */
for( j=0 ; j<3 ; ++j )
{ /* Row loop */
for( i=0 ; i<5 ; ++i )
{ /* Column loop */
_setfillmask(patterns[SOLID_FILL]); /* Set to solid fill in color */
_setcolor( color ); /* Set the same border color */
/* fill the rectangle */
_rectangle( _GFILLINTERIOR, x, y, x+width, y+height );
if( color == BLACK )
{ /* If box was black... */
_setcolor( WHITE ); /* Set drawing color to white */
_rectangle( _GBORDER, x, y, x+width, y+height ); /* Outline black in white*/
}
itoa( color, cnum, 10 ); /* Convert # to ASCII */
twidth = _getgtextextent ( cnum );
cp = _moveto( x +((width-twidth)/2), y+height+4 ); /* Show color # */
_outgtext ( cnum );
cp = _getcurrentposition ();
color = ++color % MaxColors; /* Advance to the next color */
x += (width / 2) * 3; /* move the column base */
} /* End of Column loop */
y += (height / 2) * 3; /* move the row base */
x = width / 2; /* reset column base */
} /* End of Row loop */
Pause(); /* Pause for user's response */
}
/* */
/* Note 15 - ARCDEMO: Display a random pattern of arcs on the screen */
/* until the user says enough. */
/* */
void ArcDemo(void)
{
int mradius; /* Maximum radius allowed */
int eangle; /* Random end angle of Arc */
int mranx, mrany, sangle;
int starty, endy, startx, endx;
double radians;
struct xycoord start, finish, fillseed;
MainWindow( "Arc Demonstration" );
StatusLine( "ESC Aborts - Press a Key to stop" );
mradius = MaxY / 10; /* Determine the maximum radius */
while( !kbhit() )
{ /* Repeat until a key is hit */
_setcolor( random( MaxColors - 1 ) + 1 ); /* Randomly select a color */
eangle = random( 358 ) + 1; /* Select an end angle */
sangle = random(eangle);
mranx = random(MaxX);
mrany = random(MaxY);
radians = torad( sangle );
startx = mranx + (int)( cos( radians ) * (double)mradius );
starty = mrany - (int)( sin( radians ) * (double)mradius );
radians = torad( eangle );
endx = mranx + (int)( cos( radians ) * (double)mradius );
endy = mrany - (int)( sin( radians ) * (double)mradius );
_arc( mranx+mradius, mrany+mradius, mranx-mradius, mrany-mradius,
startx, starty, endx, endy );
_getarcinfo (&start, &finish, &fillseed); /* Read coord data */
cp = _moveto (mranx, mrany);
_lineto( start.xcoord, start.ycoord ); /* line from start to center */
cp = _moveto (mranx, mrany);
_lineto( finish.xcoord, finish.ycoord ); /* line from end to center */
} /* End of WHILE not KBHIT */
Pause(); /* Wait for user's response */
}
/* */
/* Note 16 - CIRCLEDEMO: Display a random pattern of circles on the */
/* screen until the user says enough. */
/* */
void CircleDemo(void)
{
int mradius; /* Maximum radius allowed */
int mranx, mrany, mranrad;
MainWindow( "Circle Demonstration" );
StatusLine( "ESC Aborts - Press a Key to stop" );
mradius = MaxY / 10; /* Determine the maximum radius */
while( !kbhit() )
{ /* Repeat until a key is hit */
_setcolor( random( MaxColors - 1 ) + 1 ); /* Randomly select a color */
mranx = random(MaxX);
mrany = random(MaxY);
mranrad = random(mradius);
_ellipse ( _GBORDER, mranx-mranrad, mrany-mranrad,
mranx+mranrad, mrany+mranrad );
} /* End of WHILE not KBHIT */
Pause(); /* Wait for user's response */
}
/* */
/* Note 17 - PIEDEMO: Display a pie chart on the screen. */
/* */
#define adjasp( y ) ((int)(AspectRatio * (double)(y)))
void PieDemo(void)
{
struct viewporttype vp;
int xcenter, ycenter, radius, lradius;
int x, y;
double radians, piesize;
int twidth, font;
float size;
MainWindow( "Pie Chart Demonstration" );
vp.left = curr_vp.left;
vp.top = curr_vp.top;
vp.right = curr_vp.right;
vp.bottom = curr_vp.bottom;
xcenter = (vp.right - vp.left) / 2; /* Center the Pie horizontally */
ycenter = (vp.bottom - vp.top) / 2+20;/* Center the Pie vertically */
radius = (vp.bottom - vp.top) / 3; /* It will cover 2/3rds screen */
piesize = (vp.bottom - vp.top) / 4.0; /* Optimum height ratio of pie */
while( (AspectRatio*radius) < piesize ) ++radius;
lradius = radius + ( radius / 5 ); /* Labels placed 20% farther */
font = roman_ndx;
changetextstyle( Fonts[font].facename, HORIZ_DIR,
Fonts[font].pixheight,
Fonts[font].avgwidth );
twidth = _getgtextextent ( "A Sample Pie Chart" );
cp = _moveto( (MaxX-twidth)/2, 6 );
_outgtext ( "A Sample Pie Chart" );
cp = _getcurrentposition ();
size = 0.5;
changetextstyle( Fonts[font].facename, HORIZ_DIR,
(int)(Fonts[font].pixheight*size),
(int)(Fonts[font].avgwidth*size) );
_setfillmask( patterns[SOLID_FILL] );
_setcolor ( RED );
_pie ( _GFILLINTERIOR, xcenter+10+radius, ycenter-adjasp(10)+radius,
xcenter+10-radius, ycenter-adjasp(10)-radius,
xcenter+10+radius, ycenter-adjasp(10),
xcenter+10, ycenter-adjasp(10)-radius);
_setcolor ( WHITE );
_pie ( _GBORDER, xcenter+10+radius, ycenter-adjasp(10)+radius,
xcenter+10-radius, ycenter-adjasp(10)-radius,
xcenter+10+radius, ycenter-adjasp(10),
xcenter+10, ycenter-adjasp(10)-radius);
radians = torad( 45 );
x = xcenter + (int)( cos( radians ) * (double)lradius );
y = ycenter - (int)( sin( radians ) * (double)lradius /* * AspectRatio */);
twidth = _getgtextextent ( "25 %" );
cp = _moveto( x+twidth/2, y );
_outgtext ( "25 %" );
cp = _getcurrentposition ();
_setfillmask( patterns[WIDE_DOT_FILL] );
_setcolor ( GREEN );
_pie ( _GFILLINTERIOR, xcenter+radius, ycenter+radius,
xcenter-radius, ycenter-radius,
xcenter, ycenter-radius,
xcenter-radius, ycenter-radius);
_setcolor ( WHITE );
_pie ( _GBORDER, xcenter+radius, ycenter+radius,
xcenter-radius, ycenter-radius,
xcenter, ycenter-radius,
xcenter-radius, ycenter-radius);
radians = torad( 113 );
x = xcenter + (int)( cos( radians ) * (double)lradius );
y = ycenter - (int)( sin( radians ) * (double)lradius /* * AspectRatio */);
twidth = _getgtextextent ( "12.5 %" );
cp = _moveto( x-twidth, y ); /* twidth/2 ?? */
_outgtext ( "12.5 %" );
cp = _getcurrentposition ();
_setfillmask( patterns[INTERLEAVE_FILL] );
_setcolor ( YELLOW );
_pie ( _GFILLINTERIOR, xcenter-10+radius, ycenter+radius,
xcenter-10-radius, ycenter-radius,
xcenter-10-radius, ycenter-radius,
xcenter-10-radius, ycenter+radius);
_setcolor ( WHITE );
_pie ( _GBORDER, xcenter-10+radius, ycenter+radius,
xcenter-10-radius, ycenter-radius,
xcenter-10-radius, ycenter-radius,
xcenter-10-radius, ycenter+radius);
radians = torad( 180 );
x = xcenter + (int)( cos( radians ) * (double)lradius );
y = ycenter - (int)( sin( radians ) * (double)lradius /* * AspectRatio */);
twidth = _getgtextextent ( "25 %" );
cp = _moveto( x-twidth, y+Fonts[roman_ndx].pixheight/2 );
_outgtext ( "25 %" );
cp = _getcurrentposition ();
_setfillmask( patterns[HATCH_FILL] );
_setcolor ( BLUE );
_pie ( _GFILLINTERIOR, xcenter+radius, ycenter+radius,
xcenter-radius, ycenter-radius,
xcenter-radius, ycenter+radius,
xcenter+radius, ycenter);
_setcolor ( WHITE );
_pie ( _GBORDER, xcenter+radius, ycenter+radius,
xcenter-radius, ycenter-radius,
xcenter-radius, ycenter+radius,
xcenter+radius, ycenter);
radians = torad( 293 );
x = xcenter + (int)( cos( radians ) * (double)lradius );
y = ycenter - (int)( sin( radians ) * (double)lradius /* * AspectRatio */);
twidth = _getgtextextent ( "37.5 %" );
cp = _moveto( x-twidth/2, y );
_outgtext ( "37.5 %" );
cp = _getcurrentposition ();
Pause(); /* Pause for user's response */
}
/* */
/* Note 18 - BARDEMO: Draw a 2-D bar chart using _rectangle. */
/* */
void BarDemo(void)
{
int barheight[] = { 1, 3, 5, 2, 4 };
int styles[] = { 1, 3, 10, 5, 9, 1 };
int xstep, ystep;
int sheight, swidth;
int twidth, theight, font;
int i, j, h;
struct viewporttype vp;
char buffer[40];
MainWindow( "2-D Bar Chart Demonstration" );
vp.left = curr_vp.left;
vp.top = curr_vp.top;
vp.right = curr_vp.right;
vp.bottom = curr_vp.bottom;
font = roman_ndx;
changetextstyle( Fonts[font].facename, HORIZ_DIR,
Fonts[font].pixheight,
Fonts[font].avgwidth );
twidth = _getgtextextent ( "These are 2-D Bars" );
cp = _moveto( (MaxX-twidth) /2, 6 );
_outgtext( "These are 2-D Bars" );
cp = _getcurrentposition ();
font = dfont_ndx;
changetextstyle( Fonts[font].facename, HORIZ_DIR,
Fonts[font].pixheight,
Fonts[font].avgwidth );
curr_vp.left = vp.left+50;
curr_vp.top = vp.top+30;
curr_vp.right = vp.right-50;
curr_vp.bottom = vp.bottom-10;
_setviewport( vp.left+50, vp.top+30, vp.right-50, vp.bottom-10 );
vp.left = curr_vp.left;
vp.top = curr_vp.top;
vp.right = curr_vp.right;
vp.bottom = curr_vp.bottom;
sheight = vp.bottom - vp.top;
swidth = vp.right - vp.left;
h = 3 * Fonts[dfont_ndx].pixheight;
theight = Fonts[dfont_ndx].pixheight;
/* Draw vertical axis */
cp = _moveto (h, h);
_lineto( h, sheight-h );
_lineto( sheight-h, sheight-h );
ystep = (sheight - (2*h) ) / 5;
xstep = (swidth - (2*h) ) / 5;
j = sheight - h;
/* Draw tick marks and numbers for vertical axis */
for( i=0 ; i<6 ; ++i )
{
cp = _moveto (h/2, j);
_lineto( h, j );
itoa( i, buffer, 10 );
twidth = _getgtextextent (buffer);
cp = _moveto( twidth/2, j-theight/2 );
_outgtext ( buffer );
cp = _getcurrentposition ();
j -= ystep;
}
j = h;
for( i=0 ; i<6 ; ++i )
{
_setfillmask( patterns[styles[i]] );
cp = _moveto (j, sheight - h);
_lineto( j, sheight- 3 - (h/2) );
itoa( i, buffer, 10 );
twidth = _getgtextextent ( buffer );
cp = _moveto( j-(twidth/2), sheight - (h/2));
_outgtext ( buffer );
cp = _getcurrentposition ();
if( i != 5 )
{
_setcolor ( 1+random(MaxColors) );
_rectangle( _GFILLINTERIOR, j, (sheight-h)-(barheight[i] * ystep),
j+xstep, sheight-h);
_setcolor ( MaxColors-1 );
_rectangle( _GBORDER, j, (sheight-h)-(barheight[i] * ystep),
j+xstep, sheight-h);
}
j += xstep;
}
Pause();
}
/* */
/* PUTPIXELDEMO: Display a pattern of random dots on the screen */
/* and pick them back up again. */
/* */
void PutPixelDemo(void)
{
int seed = 1958;
int i, x, y, h, w, color;
struct viewporttype vp;
MainWindow( "_setpixel / _getpixel Demonstration" );
// getviewsettings( &vp );
vp.left = curr_vp.left;
vp.top = curr_vp.top;
vp.right = curr_vp.right;
vp.bottom = curr_vp.bottom;
h = vp.bottom - vp.top;
w = vp.right - vp.left;
srand( seed ); /* Restart random # function */
for( i=0 ; i<5000 ; ++i )
{ /* Put 5000 pixels on screen */
x = 1 + random( w - 1 ); /* Generate a random location */
y = 1 + random( h - 1 );
color = random( MaxColors );
_setcolor( color );
_setpixel( x, y );
}
srand( seed ); /* Restart Random # at same # */
for( i=0 ; i<5000 ; ++i )
{ /* Take the 5000 pixels off */
x = 1 + random( w - 1 ); /* Generate a random location */
y = 1 + random( h - 1 );
color = _getpixel( x, y ); /* Read the color pixel */
if( color == random( MaxColors ) ) /* Used to keep RANDOM in sync */
{
_setcolor ( 0 );
_setpixel( x, y ); /* Write pixel to BLACK */
}
}
Pause(); /* Wait for user's response */
}
/* */
/* PUTIMAGEDEMO */
/* */
void PutImageDemo(void)
{
static int r = 20;
static int StartX = 100;
static int StartY = 50;
int seed = 2047;
struct viewporttype vp;
int PauseTime, x, y, ulx, uly, lrx, lry, size, i, width, height, step;
void *Saucer;
MainWindow("_getimage / _putimage Demonstration");
StatusLine( "ESC Aborts - Press a Key to stop" );
vp.left = curr_vp.left;
vp.top = curr_vp.top;
vp.right = curr_vp.right;
vp.bottom = curr_vp.bottom;
/* Draw Saucer */
_setfillmask( patterns[SOLID_FILL] );
_setcolor ( MaxColors );
_ellipse ( _GFILLINTERIOR, StartX+r, StartY+((r/3)+2),
StartX-r, StartY-((r/3)+2) );
cp = _moveto (StartX+7, StartY-6);
_lineto(StartX+10, StartY-12);
_ellipse (_GBORDER, StartX+8, StartY-14, StartX+12, StartY-10);
cp = _moveto (StartX-7, StartY-6);
_lineto(StartX-10, StartY-12);
_ellipse (_GBORDER, StartX-12, StartY-14, StartX-8, StartY-10);
/* Read saucer image */
ulx = StartX-(r+1);
uly = StartY-14;
lrx = StartX+(r+1);
lry = StartY+(r/3)+3;
width = lrx - ulx + 1;
height = lry - uly + 1;
size = _imagesize(ulx, uly, lrx, lry);
Saucer = malloc( size );
_getimage(ulx, uly, lrx, lry, Saucer);
_putimage(ulx, uly, Saucer, _GXOR);
/* Plot some "stars" */
for ( i=0 ; i<1000; ++i )
{
_setcolor (random( MaxColors-1 )+1);
_setpixel(random(MaxX), random(MaxY) );
}
x = MaxX / 2;
y = MaxY / 2;
PauseTime = 70;
/* Restart random number generator with prime seed to ensure largest
cycle of random numbers.
*/
srand(seed);
/* until a key is hit */
while ( !kbhit() )
{
/* Draw the Saucer */
_putimage(x, y, Saucer, _GXOR); /* draw image */
delay(PauseTime);
_putimage(x, y, Saucer, _GXOR); /* erase image */
/* Move Saucer */
step = random( 2*r );
if ((step/2) % 2 != 0 )
step = -1 * step;
x = x + step;
step = random( r );
if ((step/2) % 2 != 0 )
step = -1 * step;
y = y + step;
if (vp.left + x + width - 1 > vp.right)
x = vp.right-vp.left-width + 1;
else
if (x < 0)
x = 0;
if (vp.top + y + height - 1 > vp.bottom)
y = vp.bottom-vp.top-height + 1;
else
if (y < 0)
y = 0;
}
free( Saucer );
Pause();
}
/* */
/* LINETODEMO: Display a pattern using moveto and lineto commands. */
/* */
#define MAXPTS 15
void LineToDemo(void)
{
struct viewporttype vp;
struct PTS points[MAXPTS];
int i, j, h, w, xcenter, ycenter;
int radius, angle, step;
double rads;
MainWindow( "_moveto/_lineto Demonstration" );
vp.left = curr_vp.left;
vp.top = curr_vp.top;
vp.right = curr_vp.right;
vp.bottom = curr_vp.bottom;
h = vp.bottom - vp.top;
w = vp.right - vp.left;
xcenter = w / 2; /* Determine the center of circle */
ycenter = h / 2;
radius = (int)((h - 30) / (AspectRatio * 2));
step = 360 / MAXPTS; /* Determine # of increments */
angle = 0; /* Begin at zero degrees */
for( i=0 ; i<MAXPTS ; ++i )
{ /* Determine circle intercepts */
rads = (double)angle * PI / 180.0; /* Convert angle to radians */
points[i].x = xcenter + (int)( cos(rads) * radius );
points[i].y = ycenter - (int)( sin(rads) * radius * AspectRatio );
angle += step; /* Move to next increment */
}
_ellipse ( _GBORDER, xcenter-radius, ycenter-radius,
xcenter+radius, ycenter+radius );
for( i=0 ; i<MAXPTS ; ++i )
{ /* Draw the chords to the circle */
for( j=i ; j<MAXPTS ; ++j )
{ /* For each remaining intersect */
cp = _moveto(points[i].x, points[i].y); /* Move to beginning of chord */
_lineto(points[j].x, points[j].y); /* Draw the chord */
}
}
Pause(); /* Wait for user's response */
}
/* */
/* CRTMODEDEMO: Demonstrate the effects of the change mode */
/* commands on the current screen. */
/* */
void CRTModeDemo(void)
{
struct viewporttype vp;
int mode, lwidth;
MainWindow( "_setvideomode Text & Graphics Demo" );
vp.left = curr_vp.left;
vp.top = curr_vp.top;
vp.right = curr_vp.right;
vp.bottom = curr_vp.bottom;
lwidth = _getgtextextent ( "Now you are in graphics mode..." );
cp = _moveto( (vp.right-vp.left-lwidth)/2, (vp.bottom-vp.top)/2 );
_outgtext ( "Now you are in graphics mode..." );
cp = _getcurrentposition ();
StatusLine( "Press any key for text mode..." );
getch();
_setvideomode( _DEFAULTMODE );
printf( "Now you are in text mode.\n\n" );
printf( "Press any key to go back to graphics..." );
getch();
_setvideomode( _MAXRESMODE );
MainWindow( "SetGraphMode / RestoreCRTMode demo" );
lwidth = _getgtextextent ( "Back in Graphics Mode..." );
cp = _moveto( (vp.right-vp.left-lwidth)/2, (vp.bottom-vp.top)/2 );
_outgtext ( "Back in Graphics Mode..." );
cp = _getcurrentposition ();
// outtextxy( (vp.right-vp.left)/2, (vp.bottom-vp.top)/2,
// "Back in Graphics Mode..." );
Pause(); /* Wait for user's response */
}
/* */
/* USERLINESTYLEDEMO: Display line styles showing the user */
/* defined line style functions. */
/* */
void UserLineStyleDemo(void)
{
int x, y, i, h, flag;
unsigned int style;
struct viewporttype vp;
MainWindow( "User Defined Line Styles" );
vp.left = curr_vp.left;
vp.top = curr_vp.top;
vp.right = curr_vp.right;
vp.bottom = curr_vp.bottom;
h = vp.bottom - vp.top;
x = 4;
y = 10;
style = 0;
i = 0;
// settextjustify( CENTER_TEXT, TOP_TEXT );
flag = TRUE; /* Set the bits in this pass */
while( x < vp.right-2 )
{ /* Draw lines across the screen */
if( flag ) /* If flag, set bits... */
style = style | (1 << i); /* Set the Ith bit in word */
else /* If no flag, clear bits */
style = style & !(0x8000 >> i); /* Clear the Ith bit in word */
_setlinestyle( style );
cp = _moveto (x, y);
_lineto( x, h-y ); /* Draw the new line pattern */
x += 5; /* Move the X location of line */
i = ++i % 16; /* Advance to next bit pattern */
if( style == 0xffff )
{ /* Are all bits set? */
flag = FALSE; /* begin removing bits */
i = 0; /* Start with whole pattern */
}
else
{ /* Bits not all set... */
if( style == 0 ) /* Are all bits clear? */
flag = TRUE; /* begin setting bits */
}
}
Pause(); /* Wait for user's response */
}
/* */
/* Note 19 - FILLSTYLEDEMO: Display with various user-defined fill */
/* patterns. */
/* */
void FillStyleDemo(void)
{
int h, w, style;
int i, j, x, y;
struct viewporttype vp;
char buffer[40];
int lwidth;
MainWindow( "User Defined Fill Styles" );
vp.left = curr_vp.left;
vp.top = curr_vp.top;
vp.right = curr_vp.right;
vp.bottom = curr_vp.bottom;
w = 2 * ((vp.right + 1) / 13);
h = 2 * ((vp.bottom - 10) / 10);
x = w / 2;
y = h / 2; /* Leave 1/2 blk margin */
style = 0;
for( j=0 ; j<3 ; ++j )
{ /* Three rows of boxes */
for( i=0 ; i<4 ; ++i )
{ /* Four column of boxes */
_setfillmask( patterns[style] ); /* Iterate thru all styles */
_setcolor (MaxColors-1); /* Set the fill style and WHITE */
_rectangle( _GBORDER, x, y, x+w, y+h ); /* Draw the border */
_rectangle( _GFILLINTERIOR, x, y, x+w, y+h ); /* Draw the actual box */
itoa( style, buffer, 10 ); /* Convert style 3 to ASCII */
lwidth = _getgtextextent ( buffer ); /* Width of this label */
cp = _moveto( x+((w-lwidth)/2), y+h+4 );
_outgtext ( buffer );
cp = _getcurrentposition ();
++style; /* Go on to next style # */
x += (w / 2) * 3; /* Go to next column */
} /* End of coulmn loop */
x = w / 2; /* Put base back to 1st column */
y += (h / 2) * 3; /* Advance to next row */
} /* End of Row loop */
Pause(); /* Wait for user's response */
}
/* */
/* Note 20 - PALETTEDEMO: Display a pattern of rectangles on the screen */
/* and change palette colors until the user says enough. */
/* */
/* Macro for mixing Red, Green, and Blue elements of color */
#define RGB(r,g,b) (((long) ((b) << 8 | (g)) << 8) | (r))
void PaletteDemo(void)
{
int i, j, x, y, color;
struct viewporttype vp;
int height, width;
int relt, gelt, belt;
MainWindow( "Palette Demonstration" );
StatusLine( "Press any key to continue, ESC to Abort" );
// getviewsettings( &vp );
vp.left = curr_vp.left;
vp.top = curr_vp.top;
vp.right = curr_vp.right;
vp.bottom = curr_vp.bottom;
width = (vp.right - vp.left) / 15; /* get width of the box */
height = (vp.bottom - vp.top) / 10; /* Get the height of the box */
x = y = 0; /* Start in upper corner */
color = 1; /* Begin at 1st color */
for( j=0 ; j<10 ; ++j )
{ /* For 10 rows of boxes */
for( i=0 ; i<15 ; ++i )
{ /* For 15 columns of boxes */
_setfillmask( patterns[SOLID_FILL]);
_setcolor ( color++ ); /* Set the color of box */
/* Draw the box */
_rectangle( _GFILLINTERIOR, x, y, x+width, y+height );
x += width + 1; /* Advance to next col */
color = 1 + (color % (MaxColors - 2)); /* Set new color */
} /* End of COLUMN loop */
x = 0; /* Goto 1st column */
y += height + 1; /* Goto next row */
} /* End of ROW loop */
while( !kbhit() )
{ /* Until user enters a key... */
relt = random (64);
gelt = random (64);
belt = random (64);
_remappalette( 1+random(MaxColors-2), RGB(relt,gelt,belt) );
}
// setallpalette( &palette );
/* Reset video mode to get palette back to its defaults */
_setvideomode (_MAXRESMODE);
Pause(); /* Wait for user's response */
}
/* */
/* POLYDEMO: Display a random pattern of polygons on the screen */
/* until the user says enough. */
/* */
#define MaxPts 6 /* Maximum # of pts in polygon */
void PolyDemo(void)
{
struct xycoord poly[ MaxPts ]; /* Space to hold datapoints */
int color; /* Current drawing color */
int i;
MainWindow( "Polygon Draw/Fill Demonstration" );
StatusLine( "ESC Aborts - Press a Key to stop" );
while( !kbhit() )
{ /* Repeat until a key is hit */
for( i=0 ; i<(MaxPts-1) ; i++ )
{ /* Determine a random polygon */
poly[i].xcoord = random( MaxX ); /* Set the x coord of point */
poly[i].ycoord = random( MaxY ); /* Set the y coord of point */
}
poly[i].xcoord = poly[0].xcoord; /* last point = first point */
poly[i].ycoord = poly[1].ycoord;
_setcolor( BLACK ); /* Clear out area behind polygon */
_polygon( _GBORDER, poly, MaxPts ); /* Draw a black border */
_polygon( _GFILLINTERIOR, poly, MaxPts ); /* Draw a black polygon */
color = 1 + random( MaxColors-1 ); /* Get a random color # (no blk)*/
_setfillmask( patterns[random(10)] ); /* Set a random fill style */
_setcolor( color ); /* Set the desired color */
_polygon( _GBORDER, poly, MaxPts ); /* Draw the polygon border */
_polygon( _GFILLINTERIOR, poly, MaxPts ); /* Draw the actual polygon */
} /* End of WHILE not KBHIT */
Pause(); /* Wait for user's response */
}
/* */
/* SAYGOODBYE: Give a closing screen to the user before leaving. */
/* */
void SayGoodbye(void)
{
struct viewporttype viewinfo; /* Structure to read viewport */
int h, w, font, lwidth;
MainWindow( "== Finale ==" );
viewinfo.left = curr_vp.left;
viewinfo.top = curr_vp.top;
viewinfo.right = curr_vp.right;
viewinfo.bottom = curr_vp.bottom;
font = roman_ndx;
changetextstyle( Fonts[font].facename, HORIZ_DIR,
Fonts[font].pixheight,
Fonts[font].avgwidth );
h = viewinfo.bottom - viewinfo.top;
w = viewinfo.right - viewinfo.left;
lwidth = _getgtextextent ( "That's all, folks!" );
cp = _moveto( (w-lwidth)/2, h/2 );
_outgtext ( "That's all, folks!" );
cp = _getcurrentposition ();
StatusLine( "Press any key to EXIT" );
getch();
_clearscreen(_GCLEARSCREEN); /* Clear the graphics screen */
}
/* */
/* PAUSE: Pause until the user enters a keystroke. If the */
/* key is an ESC, then exit program, else simply return. */
/* */
void Pause(void)
{
static char msg[] = "Esc aborts or press a key...";
int c;
StatusLine( msg ); /* Put msg at bottom of screen */
c = getch(); /* Read a character from kbd */
if( ESC == c )
{ /* Does user wish to leave? */
_setvideomode( _DEFAULTMODE ); /* Change to text mode */
exit( 1 ); /* Return to OS */
}
if( c == 0 )
{ /* Did use hit a non-ASCII key? */
c = getch(); /* Read scan code for keyboard */
}
_clearscreen(_GCLEARSCREEN); /* Clear the screen */
}
/* */
/* MAINWINDOW: Establish the main window for the demo and set */
/* a viewport for the demo code. */
/* */
void MainWindow( char *header )
{
int height, twidth, font;
_clearscreen(_GCLEARSCREEN); /* Clear graphics screen */
_setcolor( MaxColors - 1 ); /* Set current color to white */
curr_vp.left = 0; /* Initial & current viewport */
curr_vp.top = 0;
curr_vp.right = MaxX;
curr_vp.bottom = MaxY;
_setviewport( 0, 0, MaxX, MaxY ); /* Open port to full screen */
height = Fonts[dfont_ndx].pixheight; /* Get basic text height */
font = dfont_ndx;
changetextstyle( Fonts[font].facename, HORIZ_DIR, height,
Fonts[font].avgwidth );
/* Need to center text ourselves */
twidth = _getgtextextent ( header );
cp = _moveto( (MaxX-twidth)/2, 2 );
_outgtext ( header );
cp = _getcurrentposition ();
curr_vp.left = 0;
curr_vp.top = height+4;
curr_vp.right = MaxX;
curr_vp.bottom = MaxY-(height+4);
_setviewport( 0, height+4, MaxX, MaxY-(height+4) );
DrawBorder();
curr_vp.left = 1;
curr_vp.top = height+5;
curr_vp.right = MaxX-1;
curr_vp.bottom = MaxY-height+5;
_setviewport( 1, height+5, MaxX-1, MaxY-(height+5) );
}
/* */
/* STATUSLINE: Display a status line at the bottom of the screen. */
/* */
void StatusLine( char *msg )
{
int height, twidth, font;
curr_vp.left = 0;
curr_vp.top = 0;
curr_vp.right = MaxX;
curr_vp.bottom = MaxY;
_setviewport( 0, 0, MaxX, MaxY ); /* Open port to full screen */
_setcolor( MaxColors - 1 ); /* Set current color to white */
font = dfont_ndx;
height = Fonts[dfont_ndx].pixheight; /* Detemine current height */
changetextstyle( Fonts[font].facename, HORIZ_DIR, height,
Fonts[font].avgwidth );
_setlinestyle( SOLID_STYLE );
_setfillmask( patterns[EMPTY_FILL] );
_rectangle( _GBORDER, 0, MaxY-(height+4), MaxX, MaxY );
/* Need to center text ourselves */
twidth = _getgtextextent ( msg );
cp = _moveto( (MaxX-twidth)/2, MaxY-(height+2) );
_outgtext ( msg );
cp = _getcurrentposition ();
curr_vp.left = 1;
curr_vp.top = height+5;
curr_vp.right = MaxX-1;
curr_vp.bottom = MaxY-(height+5);
_setviewport( 1, height+5, MaxX-1, MaxY-(height+5) );
}
/* */
/* DRAWBORDER: Draw a solid single line around the current */
/* viewport. */
/* */
void DrawBorder(void)
{
struct viewporttype vp;
_setcolor( MaxColors - 1 ); /* Set current color to white */
_setlinestyle( SOLID_STYLE );
vp.left = curr_vp.left;
vp.top = curr_vp.top;
vp.right = curr_vp.right;
vp.bottom = curr_vp.bottom;
_rectangle( _GBORDER, 0, 0, vp.right-vp.left, vp.bottom-vp.top );
}
/* */
/* Note 21 - CHANGETEXTSTYLE: similar to Borland C++ settextstyle, but */
/* checks forerrors that might occur while loading the font */
/* file. */
/* */
void changetextstyle(char *font, int direction, int charht, int charwid)
/* font is name of typeface */
/* direction is orientation - horizontal or vertical */
/* charht and charwid are used only for vector fonts */
{
int ErrorCode;
unsigned char list[50];
/* Construct string of font characteristics */
sprintf( list, "t'%s'h%dw%d", font, charht, charwid );
/* Select the font */
ErrorCode =_setfont( list );
if( ErrorCode >= 0 )
{
}
/* Set up direction for _outgtext */
if (direction == HORIZ_DIR)
_setgtextvector ( 1, 0 );
else
_setgtextvector ( 0, 1 );
}
/* */
/* GPRINTF: Used like PRINTF except the output is sent to the */
/* screen in graphics mode at the specified co-ordinate. */
/* */
int gprintf( int *xloc, int *yloc, char *fmt, ... )
/* Must be used with _setfont for default font with index dfont_ndx */
{
va_list argptr; /* Argument list pointer */
char str[140]; /* Buffer to build sting into */
int cnt; /* Result of SPRINTF for return */
va_start( argptr, fmt ); /* Initialize va_ functions */
cnt = vsprintf( str, fmt, argptr ); /* prints string to buffer */
cp = _moveto( *xloc, *yloc );
_outgtext ( str ); /* Send string in graphics mode */
cp = _getcurrentposition ();
*yloc += Fonts[dfont_ndx].pixheight + 2; /* Advance to next line */
va_end( argptr ); /* Close va_ functions */
return( cnt ); /* Return the conversion count */
}
/* Note 22 - the delay function pauses for wait microseconds. */
void delay( clock_t wait )
{
clock_t goal;
goal = wait + clock();
while( goal > clock() )
;
}